<?php declare(strict_types=1);
/**
 * @author      xianganyall <xianganyall@gmail.com>
 * @copyright   2023-2025 owner
 **/

namespace Srv\Libs\Common;

use Exception;

final class CommJson
{
    public const JSON_DEFAULT_EMPTY_STRING  = '[]';     // 默认空
    public const JSON_ARRAY_EMPTY_STRING    = '[]';     // 数组空
    public const JSON_OBJECT_EMPTY_STRING   = '{}';     // 对象空
    public const JSON_DEFAULT_OPTIONS       = JSON_UNESCAPED_UNICODE|JSON_PRESERVE_ZERO_FRACTION;   // 默认JSON配置

    /**
     * @param string $jsonStr
     * @param bool $isObject
     * @return bool
     * isJsonString
     */
    public static function isJsonString(string $jsonStr, bool &$isObject = false):bool
    {
        try{
            $jsonObject = @json_decode($jsonStr);
            if(json_last_error() !== JSON_ERROR_NONE) return false;
            $isObject   = is_object($jsonObject);
        }catch(Exception $Exception){
            unset($Exception);
            return false;
        }
        return true;
    }

    /**
     * @param array $jsonData
     * @param string $emptyJson
     * @param int $options
     * @param bool $isFail
     * @return string
     * encodeArray
     */
    public static function encodeArray(array $jsonData, string $emptyJson = self::JSON_DEFAULT_EMPTY_STRING, int $options = self::JSON_DEFAULT_OPTIONS, bool &$isFail = false):string
    {
        if(CommArray::isEmpty($jsonData)) return $emptyJson;
        $jsonStr    = @json_encode($jsonData, $options);
        $isFail     = json_last_error() !== JSON_ERROR_NONE;
        if(!is_string($jsonStr)) $jsonStr = $emptyJson;
        return $jsonStr;
    }

    /**
     * @param array $jsonData
     * @param string $emptyJson
     * @param int $options
     * @param bool $isFail
     * @return string
     * encodeArrayPretty
     */
    public static function encodeArrayPretty(array $jsonData, string $emptyJson = self::JSON_DEFAULT_EMPTY_STRING, int $options = self::JSON_DEFAULT_OPTIONS, bool &$isFail = false):string
    {
        return self::encodeArray($jsonData, $emptyJson, $options | JSON_PRETTY_PRINT, $isFail);
    }

    /**
     * @param $jsonData
     * @param string $emptyJson
     * @param int $options
     * @param bool $isFail
     * @return string
     * encode
     */
    public static function encode($jsonData, string $emptyJson = self::JSON_DEFAULT_EMPTY_STRING, int $options = self::JSON_DEFAULT_OPTIONS, bool &$isFail = false):string
    {
        $jsonStr    = @json_encode($jsonData, $options);
        $isFail     = json_last_error() !== JSON_ERROR_NONE;
        if(!is_string($jsonStr)) $jsonStr = $emptyJson;
        return $jsonStr;
    }

    /**
     * @param $jsonData
     * @param string $emptyJson
     * @param int $options
     * @param bool $isFail
     * @return string
     * encodePretty
     */
    public static function encodePretty($jsonData, string $emptyJson = self::JSON_DEFAULT_EMPTY_STRING, int $options = self::JSON_DEFAULT_OPTIONS, bool &$isFail = false):string
    {
        return self::encode($jsonData, $emptyJson, $options | JSON_PRETTY_PRINT, $isFail);
    }

    /**
     * @param string $jsonStr
     * @param bool $isFail
     * @return array
     * decodeArray
     */
    public static function decodeArray(string $jsonStr, bool &$isFail = false):array
    {
        $jsonData = @json_decode($jsonStr, true);
        $isFail   = json_last_error() !== JSON_ERROR_NONE;
        if(!is_array($jsonData)) $jsonData = [];
        return $jsonData;
    }

    /**
     * @param string $jsonStr
     * @param bool $isArray
     * @param bool $isFail
     * @return array|mixed
     * decode
     */
    public static function decode(string $jsonStr, bool $isArray = true, bool &$isFail = false)
    {
        $jsonData = @json_decode($jsonStr, $isArray);
        $isFail   = json_last_error() !== JSON_ERROR_NONE;
        if($isArray && !is_array($jsonData)) $jsonData = [];
        return $jsonData;
    }

    /**
     * @param string $text
     * @return string
     * getJsonStr
     */
    public static function getJsonStr(string $text):string
    {
        $textNew        = preg_replace('/[\n\r]+/', '', $text);
        if(is_string($textNew)) $text = trim($textNew);
        $textLength     = strlen($text);
        if($textLength < 3) return '';
        if($textLength >= 7 && preg_match('/({.+})/', $text, $match)) return $match[1]??'';
        if(preg_match('/(\[.+])/', $text, $match)) return $match[1]??'';
        return '';
    }
}